Using IIS Compression

By Yanbing Shi

The article provides an overview on how to use IIS Compression.

Compression Level

HTTP compression is a trade-off of CPU for bandwidth. For a given compression algorithm, achieving higher compression ratio typically comes with slower compression speed, and vice versa. The balance between compression ratio and speed is controlled by the compression level. The compression levels of iiszlib.dll, iisbrotli.dll, and gzip.dll do not match with each other in terms of range, compression ratio, and speed. The comparison of the allowed compression levels of the three compression scheme providers is summarized in the below table.

Compression Scheme Provider Compression Level: No Compression Compression Level: Best Speed Compression Level: Best Compression Ratio
gzip.dll N/A 0 10
iiszlib.dll 0 1 9
iisbrotli.dll N/A 0 11

Note

Level 0 of iiszlib.dll specifies no compression rather than best-speed compression. The default IIS dynamicCompressionLevel attribute value in the <httpCompression> element is 0 as well. Therefore, dynamicCompressionLevel needs to be explicitly set above 0 to allow iiszlib.dll to compress dynamically generated contents.

Compression Scheme Prioritization

HTTP Compression Scheme Negotiation

The compression scheme negotiation between user agents and IIS servers complies with Requests For Comment (RFC) specification 7231:

  1. The negotiation starts with the user agent specifying the list of acceptable compression schemes in the Accept-Encoding request header.

  2. The server examines the Accept-Encoding header in the request and selects a scheme that the server supports.

  3. The server applies the corresponding algorithm to compress the response body.

  4. When the server sends back the response, it adds the Content-Encoding response header with the selected compression scheme as the header value.

  5. The user agent uses the scheme indicated in the Content-Encoding response header to decompress the response body and to render the original contents to the user.

Enabling Multiple Compression Schemes

One of the key ideas behind HTTP compression scheme negotiation is the possibility of supporting new compression schemes while maintaining backward compatibility with old clients or servers.

While Brotli compression offers the benefit of higher compression ratio and has been supported by many browsers, it is still not as widely adopted as Gzip at the time of writing. Therefore, one possible optimization is to enable both Brotli and Gzip compression, but prioritize Brotli if the client-side user agent also supports it.

IIS 10.0 Version 1803 or Above

Compression scheme prioritization is supported in IIS 10.0 version 1803 or above. The priority of each compression scheme is determined by its order in the <scheme> collection of the <httpCompression>element:

  • A compression scheme appearing on the top of the <scheme> collection is prioritized over the one appearing after, if their quality values specified in the Accept-Encoding request header value are the same.
  • A compression scheme with higher quality value in the Accept-Encoding request header value is prioritized over the one with lower quality value regardless of their order in the <scheme> collection.

The installation of IIS Compression registers iisbrotli.dll and iiszlib.dll as the br and gzip compression scheme providers, respectively, and places br before gzip in the <scheme> collection:

<scheme name="br" dll="%ProgramFiles%\IIS\IIS Compression\iisbrotli.dll" />
<scheme name="gzip" dll="%ProgramFiles%\IIS\IIS Compression\iiszlib.dll" />

Such configuration order allows the IIS server to prioritize Brotli over Gzip when most browsers that support Brotli use Accept-Encoding: gzip, deflate, br for compression scheme negotiation.

Note

Typically the browsers that support Brotli compression only advertise br in the Accept-Encoding header value when HTTPS is used.

Before IIS 10.0 Version 1803

Although IIS prior to version 10.0 version 1803 allows enabling multiple compression schemes, but it prioritizes the compression scheme based on the scheme order appearing in the Accept-Encoding request header value:

  • A compression scheme appearing first (from left to right) in the Accept-Encoding request header value is prioritized over the one appearing after, if they have the same quality values.
  • A compression scheme with higher quality value is prioritized over the one with lower quality value regardless of their order in the Accept-Encoding request header value.

In consequence, IIS always prioritizes gzip over br for the typical scenario that the browser sets Accept-Encoding: gzip, deflate, br header in the request.

A possible workaround is installing the URL Rewrite Module and configuring a rewrite rule to modify the Accept-Encoding header value. The following configuration shows a sample rewrite rule that rewrites the Accept-Encoding header value to only include br scheme if it finds the string br in the header value with a non-zero quality value.

<rewrite>
    <allowedServerVariables>
        <add name="HTTP_ACCEPT_ENCODING" />
    </allowedServerVariables>
    <rules>
        <rule name="Prioritize Brotli">
            <match url=".*" />
            <conditions>
                <add input="{HTTP_ACCEPT_ENCODING}" pattern="\bbr(?!;q=0)\b" />
            </conditions>
            <serverVariables>
                <set name="HTTP_ACCEPT_ENCODING" value="br" />
            </serverVariables>
        </rule>
    </rules>
</rewrite>

More details on how to configure rewrite rules can be found in Creating Rewrite Rules for the URL Rewrite Module.

Testing IIS Compression

Testing IIS Compression can be accomplished by:

  • Opening a browser and requesting certain contents from the IIS server.
  • Checking the requests and responses through the developer tools of the browser.

Response headers from F12 tools

To test IIS Compression for static content compression:

  • Ensure the MIME type of the requested resource is enabled in the <staticTypes> collection in the <httpCompression> element.
  • Ensure the requested resource size is larger than minFileSizeForComp specified in <httpCompression> element.
  • Ensure the "hit frequency" threshold is reached for the requested URL. The threshold is specified by the frequentHitThreshold and frequentHitTimePeriod attributes in the <serverRuntime> element. Alternatively, set the value of the staticCompressionIgnoreHitFrequency attribute in the <httpCompression> element as true to disable the "hit frequency" check just for testing purpose.

To test IIS Compression for dynamic content compression:

  • Ensure the MIME type of the requested resource is enabled in the <dynamicTypes> collection in the <httpCompression> element.